package dao

import (
	"driver_srv/basic/config"
	__ "driver_srv/basic/driverproto"
	"driver_srv/handler/models"
	"driver_srv/untils"
	"errors"
	"time"
)

// 添加车辆
func VehicleAdd(in *__.VehicleAddReq) (*models.Vehicle, error) {
	var err error
	tx := config.DB.Begin()
	defer func() {
		if r := recover(); r != nil {
			tx.Rollback()
		}
	}()
	// 定义锁键，使用车牌号保证锁的唯一性
	lockKey := "vehicle_add_lock" + in.LicensePlate
	// 尝试获取锁，设置过期时间为 10 秒，防止死锁
	ctx := config.Ctx
	ok, err := config.Rdb.SetNX(ctx, lockKey, 1, 3*time.Second).Result()
	if err != nil {
		return nil, errors.New("获取分布式锁失败: " + err.Error())
	}
	if !ok {
		return nil, errors.New("当前车辆添加操作正在进行中，请稍后再试")
	}
	//// 获取锁成功后，在函数结束时释放锁
	defer func() {
		config.Rdb.Del(ctx, lockKey)
	}()
	//查询司机是否存在
	var driver models.Driver
	if err = driver.GetDriverId(in.DeviceId); err != nil {
		return nil, errors.New("司机查询不存在")
	}
	if driver.Id == 0 {
		return nil, errors.New("司机不存在")
	}
	// 获取车辆证件存在
	var vehicleFiles models.VehicleFiles
	if err = vehicleFiles.GetVehicleFilesById(int32(in.VehicleFilesId)); err != nil {
		return nil, errors.New("车辆证件查询不存在")
	}
	if vehicleFiles.Id == 0 {
		return nil, errors.New("车辆证件不存在")
	}
	var vehicle models.Vehicle
	//校验车牌号
	if !untils.LicensePlateRegexp(in.LicensePlate) {
		return nil, errors.New("车牌号格式错误")
	}

	//校验VIN码
	if !untils.VinCodeRegexp(in.VinCode) {
		return nil, errors.New("VIN码格式错误")
	}

	//校验车载大脑编号
	if !untils.CarBrainNumberRegexp(in.CarBrainNumber) {
		return nil, errors.New("车载大脑编号格式错误")
	}

	//校验大屏编号
	if !untils.LargeScreenNumberRegexp(in.LargeScreenNumber) {
		return nil, errors.New("大屏编号格式错误")
	}
	//创建车辆
	vehicle = models.Vehicle{
		DriverId:            int32(in.DeviceId),           //司机ID
		VehicleFilesID:      int32(in.VehicleFilesId),     //车辆证件ID
		CityId:              int32(in.CityId),             //城市ID
		LevelId:             int32(in.LevelId),            //车辆级别ID
		ModelId:             int32(in.ModelId),            //车型ID
		VinCode:             in.VinCode,                   //校验VIN码
		LicensePlate:        in.LicensePlate,              //校验车牌号
		IsInstalledCarBrain: int8(in.IsInstalledCarBrain), //是否安装车载大脑 0-否 1-是
		CarBrainBrand:       in.CarBrainBrand,             //车载大脑品牌
		CarBrainNumber:      in.CarBrainNumber,            //校验车载大脑编号
		LargeScreenBrand:    in.LargeScreenBrand,          //大屏品牌
		LargeScreenNumber:   in.LargeScreenNumber,         //校验大屏编号
		Status:              1,                            //状态 1:启用  2:停用
		Bind:                1,                            //车辆绑定:  1:绑定  2:解除
	}
	if err = vehicle.CreateVehicle(); err != nil {
		return nil, errors.New("创建车辆失败")
	}
	// 提交事务
	if err = tx.Commit().Error; err != nil {
		return nil, errors.New("提交事务失败")
	}
	return &vehicle, nil
}

// 车辆证件添加
func VehicleFilesAdd(in *__.VehicleFilesAddReq) (*models.VehicleFiles, error) {
	var err error
	//添加车辆证件
	var vehicleFiles models.VehicleFiles
	vehicleFiles = models.VehicleFiles{
		VehicleInvoicePath:          in.VehicleInvoicePath,
		CertificatePath:             in.CertificatePath,
		DrivingProofPath:            in.DrivingProofPath,
		RegistrationCertificatePath: in.RegistrationCertificatePath,
		TaxProofPath:                in.TaxProofPath,
		VehicleTransportCertPath:    in.VehicleTransportCertPath,
		OtherOnePath:                in.OtherOnePath,
		OtherTwoPath:                in.OtherTwoPath,
	}
	if err = vehicleFiles.VehicleFilesAdd(); err != nil {
		return nil, errors.New("车辆证件图片添加失败")
	}
	return &vehicleFiles, err
}

// 网约车添加
func RideHailingAdd(in *__.RideHailingAddReq) (*models.RideHailing, error) {
	var err error
	//查询司机是否存在
	var driver models.Driver
	if err = driver.GetDriverId(in.DeviceId); err != nil {
		return nil, errors.New("司机查询不存在")
	}
	if driver.Id == 0 {
		return nil, errors.New("司机不存在")
	}
	//解析时间
	registrationDate, err := time.Parse("2006-01-02", in.RegistrationDate)
	if err != nil {
		return nil, errors.New("车辆注册日期格式错误")
	}
	permitValidFrom, err := time.Parse("2006-01-02", in.PermitValidFrom)
	if err != nil {
		return nil, errors.New("车辆运输证有效期起格式错误")
	}
	permitValidTo, err := time.Parse("2006-01-02", in.PermitValidTo)
	if err != nil {
		return nil, errors.New("车辆运输证有效期止格式错误")
	}
	firstRegistrationDate, err := time.Parse("2006-01-02", in.FirstRegistrationDate)
	if err != nil {
		return nil, errors.New("车辆初次登记日期格式错误")
	}
	nextInspectionDate, err := time.Parse("2006-01-02", in.NextInspectionDate)
	if err != nil {
		return nil, errors.New("车辆下次年检时间格式错误")
	}
	gpsInstallationDate, err := time.Parse("2006-01-02", in.GpsInstallationDate)
	if err != nil {
		return nil, errors.New("卫星定位设备安装日期格式错误")
	}
	devicePurchaseDate, err := time.Parse("2006-01-02", in.DevicePurchaseDate)
	if err != nil {
		return nil, errors.New("设备购日期格式错误")
	}
	//校验发动机号/电动机号
	if !untils.EngineOrMotorNumberRegexp(in.EngineOrMotorNumber) {
		return nil, errors.New("发动机号/电动机号格式错误")
	}
	//网约车添加
	var rideHailing models.RideHailing
	rideHailing = models.RideHailing{
		CompanyIdentifier:          in.CompanyIdentifier,           //公司标识
		VehicleBrand:               in.VehicleBrand,                //车辆厂牌
		VehicleType:                in.VehicleType,                 //车辆类型
		VehicleOwner:               in.VehicleOwner,                //车辆所有人
		EngineOrMotorNumber:        in.EngineOrMotorNumber,         //校验发动机号/电动机号
		RegistrationDate:           registrationDate,               //车辆注册日期
		FuelType:                   in.FuelType,                    //燃油类型
		EngineDisplacement:         float64(in.EngineDisplacement), //发动机排量
		VehiclePhotoFileNumber:     in.VehiclePhotoFileNumber,      //车辆照片文件编号
		TransportationPermitNumber: in.TransportationPermitNumber,  //运输证字号
		PermitIssuingAuthority:     in.PermitIssuingAuthority,      //车辆运输证发证机构
		OperationArea:              in.OperationArea,               //车辆经营区域
		PermitValidFrom:            permitValidFrom,                //车辆运输证有效期起
		PermitValidTo:              permitValidTo,                  //车辆运输证有效期止
		FirstRegistrationDate:      firstRegistrationDate,          //车辆初次登记日期
		MaintenanceStatus:          in.MaintenanceStatus,           //车辆检修状态
		NextInspectionDate:         nextInspectionDate,             //车辆下次年检时间
		AnnualInspectionStatus:     in.AnnualInspectionStatus,      //车辆年度审核状态
		InvoicePrinterSerialNumber: in.InvoicePrinterSerialNumber,  //发票打印设备序列号
		GpsBrand:                   in.GpsBrand,                    //卫星定位装置品牌
		GpsModel:                   in.GpsModel,                    //卫星定位装置型号
		GpsImei:                    in.GpsImei,                     //卫星定位装置IMEI号
		GpsInstallationDate:        gpsInstallationDate,            //卫星定位设备安装日期
		DevicePurchaseDate:         devicePurchaseDate,             //设备购日期
		ServiceType:                in.ServiceType,                 //服务类型
		FreightTypeCode:            in.FreightTypeCode,             //运价类型编码
		DriverId:                   int32(in.DeviceId),             //司机ID
	}
	if err = rideHailing.CreateRideHailing(); err != nil {
		return nil, errors.New("网约车添加加失败")
	}

	return &rideHailing, nil
}

// 车辆展示
func ListVehicle(in *__.ListVehicleReq) ([]*__.ListVehicle, error) {
	var err error
	//查询车辆信息
	var vehicle models.Vehicle
	listVehicle, err := vehicle.ListVehicle()
	if err != nil {
		return nil, errors.New("车辆查询失败")
	}
	var vehicleList []*__.ListVehicle
	for _, r := range listVehicle {
		vehicleList = append(vehicleList, &__.ListVehicle{
			Id:     int64(r.Id),
			Status: int64(r.Status),
			Bind:   r.Bind,
			Level:  r.Level,
			Model:  r.Model,
		})
	}
	return vehicleList, nil
}
